/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Model', {
	init: function(canvas, modelConfig) {
		var me = this, model = canvas.paper[modelConfig.type]().attr(modelConfig.attrs),
				config = {
					flowFrom: modelConfig.type === 'path' ? null : [],
					flowTo: modelConfig.type === 'path' ? null : [],
					canvas: canvas, coreX: 0, coreY: 0
				};
		model.id = model.node.raphaelid = canvas.createId(canvas, model.type, modelConfig.modelId);
		model.data(modelConfig.data);
		Ext.apply(model, config);
		if (!canvas.readOnly) {
			model.drag(me.onDDMove, me.onDDStart, me.onDDEnd);
		}
		var bbox = model.getBBox();
		model.coreX = bbox.cx;
		model.coreY = bbox.cy;
		if (modelConfig.text) {
			var text = canvas.paper.text().attr(modelConfig.text.attrs);
			model.text = text;
			text.model = model;
			var bbox = text.getBBox();
			text.coreX = bbox.cx;
			text.coreY = bbox.cy;
		}
		return model;
	},
	onDDStart: function(x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox,
				lineX = canvas.lineX, pathX = lineX.attrs.path,
				lineY = canvas.lineY, pathY = lineY.attrs.path;
		lineX.show();
		lineY.show();
		selectBox.oldX = selectBox.attrs.x;
		selectBox.oldY = selectBox.attrs.y;
		pathX[0][1] = pathX[1][1] = -10;
		lineX.attr({path: pathX});
		pathY[0][2] = pathY[1][2] = -10;
		lineY.attr({path: pathY});
	},
	onDDMove: function(dx, dy, x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox,
				lineX = canvas.lineX, pathX = lineX.attrs.path,
				lineY = canvas.lineY, pathY = lineY.attrs.path,
				newX = selectBox.oldX + dx, newY = selectBox.oldY + dy;
		newX = Raphael.snapTo(5, newX);
		newY = Raphael.snapTo(5, newY);
		selectBox.attr({x: newX, y: newY});
		pathX[0][1] = pathX[1][1] = selectBox.attrs.x + selectBox.attrs.width / 2;
		lineX.attr({path: pathX});
		pathY[0][2] = pathY[1][2] = selectBox.attrs.y + selectBox.attrs.height / 2;
		lineY.attr({path: pathY});
	},
	onDDEnd: function(x, y, e) {
		var model = this, canvas = model.canvas, selectBox = canvas.selectBox;
		var offsetX = selectBox.attrs.x - selectBox.oldX,
				offsetY = selectBox.attrs.y - selectBox.oldY;
		Ext.each(canvas.selected, function(model) {
			if (model.type === 'circle' || model.type === 'ellipse') {
				model.oldX = model.attrs.cx;
				model.oldY = model.attrs.cy;
				model.attr({cx: model.oldX + offsetX, cy: model.oldY + offsetY});
			} else {
				model.oldX = model.attrs.x;
				model.oldY = model.attrs.y;
				model.attr({x: model.oldX + offsetX, y: model.oldY + offsetY});
			}
			var bbox = model.getBBox();
			model.coreX = bbox.cx;
			model.coreY = bbox.cy;
			if (model.text) {
				model.text.attr({x: model.coreX, y: bbox.y2 + 10});
			}
			Ext.each(model.flowFrom, function(ff) {
				var oldCoreStart = ff.start, path = ff.attrs.path, len = path.length;
				if (ff.flowFrom) {
					oldCoreStart = [ff.flowFrom.coreX, ff.flowFrom.coreY];
					path[len - 2] = ['M', oldCoreStart[0], oldCoreStart[1]];
				}
				path[len - 1] = ['L', model.coreX, model.coreY];
				ff.attr({path: path});
				canvas.connect(ff);
			});
			Ext.each(model.flowTo, function(ft) {
				var oldCoreEnd = ft.end, path = ft.attrs.path;
				if (ft.flowTo) {
					oldCoreEnd = [ft.flowTo.coreX, ft.flowTo.coreY];
					path[1] = ['L', oldCoreEnd[0], oldCoreEnd[1]];
				}
				path[0] = ['M', model.coreX, model.coreY];
				ft.attr({path: path});
				canvas.connect(ft);
			});
		});
		canvas.lineX.hide();
		canvas.lineY.hide();
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Circle', {
	extend: 'SvgEditor.graph.Model'
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Ellipse', {
	extend: 'SvgEditor.graph.Model'
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Rect', {
	extend: 'SvgEditor.graph.Model'
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Anchor', {
	extend: 'SvgEditor.graph.Circle',
	onDDStart: function(x, y, e) {
		var anchor = this, canvas = anchor.canvas, model = canvas.selected[0];
		anchor.oldX = anchor.attrs.cx;
		anchor.oldY = anchor.attrs.cy;
		anchor.toBack();
		if (anchor.id === 'startP' || anchor.id === 'endP') {
			var flow = model, flowFrom = flow.flowFrom, flowTo = flow.flowTo, start, end;
			if (flowFrom) {
				start = [flowFrom.coreX, flowFrom.coreY];
			} else {
				start = flow.start;
			}
			if (flowTo) {
				end = [flowTo.coreX, flowTo.coreY];
			} else {
				end = flow.end;
			}
			flow.attr({path: [
					['M', start[0], start[1]],
					['L', end[0], end[1]]
				]});
			flow.start = start;
			flow.end = end;
		}
	},
	onDDMove: function(dx, dy, x, y, e) {
		var anchor = this, model = anchor.canvas.selected[0];
		anchor.attr({cx: anchor.oldX + dx, cy: anchor.oldY + dy});
		anchor.coreX = anchor.attrs.cx;
		anchor.coreY = anchor.attrs.cy;
		if (anchor.id === 'startP') {
			var flow = model;
			flow.attr({path: [
					['M', anchor.coreX, anchor.coreY],
					['L', flow.end[0], flow.end[1]]
				]});
		} else if (anchor.id === 'endP') {
			var flow = model;
			flow.attr({path: [
					['M', flow.start[0], flow.start[1]],
					['L', anchor.coreX, anchor.coreY]
				]});
		}
	},
	onDDEnd: function(x, y, e) {
		var anchor = this, canvas = anchor.canvas, model = canvas.selected[0];
		if (model.type === 'path') {
			var flow = model, flowPlate = flow.flowPlate, path = flow.attrs.path;
			flowPlate.attr({path: path});
			flowPlate.start = flow.start = [path[0][1], path[0][2]];
			flowPlate.end = flow.end = [path[1][1], path[1][2]];
			if (anchor.id === 'startP') {
				canvas.connect(flow, canvas.target, null, true);
			}
			if (anchor.id === 'endP') {
				canvas.connect(flow, null, canvas.target, true);
			}
			canvas.viewAnchor(canvas, flow);
		}
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Image', {
	extend: 'SvgEditor.graph.Rect',
	init: function(canvas, modelConfig) {
		var me = this;
//		, img = canvas.img;
//		img.setSrc(modelConfig.attrs.src);
//		var width = img.getWidth(), height = img.getHeight();
//		modelConfig.attrs.width = width;
//		modelConfig.attrs.height = height;
		var model = me.callParent(arguments);
//		img.setSize(1, 1);
		return model;
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Path', {
	extend: 'SvgEditor.graph.Model',
	init: function(canvas, modelConfig, noPlate) {
		var me = this, config = {
			start: [0, 0], end: [0, 0]
		};
		var flow = me.callParent(arguments);
		Ext.apply(flow, config);
		if (!noPlate) {
			var path = flow.attrs.path, len = path.length, flowPlate = flow.clone().
					attr({'arrow-end': '', 'stroke-width': 16, stroke: 'white'}).toBack()
			flow.flowPlate = flowPlate;
			flowPlate.flow = flow;
			flowPlate.start = flow.start = [path[0][1], path[0][2]];
			flowPlate.end = flow.end = [path[len - 1][1], path[len - 1][2]];
			if (!canvas.readOnly) {
				flowPlate.drag(me.onPlateMove, me.onDDStart, me.onPlateEnd);
			}
		}
		return flow;
	},
	onDDStart: function(x, y, e) {

	},
	onDDMove: function(dx, dy, x, y, e) {
		var flow = this, path = [
			['M', flow.start[0] + dx, flow.start[1] + dy],
			['L', flow.end[0] + dx, flow.end[1] + dy]
		];
		flow.attr({path: path});
		if (flow.flowPlate) {
			flow.flowPlate.attr({path: path});
		}
	},
	onDDEnd: function(x, y, e) {
		var flow = this, flowPlate = flow.flowPlate, canvas = flow.canvas, path = flow.attrs.path;
		flow.start = [path[0][1], path[0][2]];
		flow.end = [path[1][1], path[1][2]];
		if (flowPlate) {
			flowPlate.start = flow.start;
			flowPlate.end = flow.end;
		}
		canvas.viewAnchor(canvas, flow);
	},
	onPlateMove: function(dx, dy, x, y, e) {
		var flowPlate = this, flow = flowPlate.flow, path = [
			['M', flow.start[0] + dx, flow.start[1] + dy],
			['L', flow.end[0] + dx, flow.end[1] + dy]
		];
		flow.attr({path: path});
		flow.flowPlate.attr({path: path});
	},
	onPlateEnd: function(x, y, e) {
		var flowPlate = this, flow = flowPlate.flow, canvas = flow.canvas, path = flow.attrs.path;
		flowPlate.start = flow.start = [path[0][1], path[0][2]];
		flowPlate.end = flow.end = [path[1][1], path[1][2]];
		canvas.viewAnchor(canvas, flow);
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.graph.Text', {
	extend: 'SvgEditor.graph.Model'
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.canvas.Operation', {
	getModelById: function(canvas, id) {
		return canvas.paper.getById(id);
	},
	setModelId: function(model, id) {
		if (model) {
			model.id = model.node.raphaelid = id;
		}
	},
	setModelAttrs: function(model, attrs) {
		if (model) {
			model.attr(attrs);
		}
	},
	getFlowFrom: function(model) {
		return model.flowFrom;
	},
	getFlowTo: function(model) {
		return model.flowTo;
	},
	createModel: function(canvas, modelConfig) {
		return canvas.mixins[modelConfig.type].init(canvas, modelConfig);
	},
	addModel: function(canvas, modelConfig, x, y, byDD) {
		canvas = canvas || this;
		if (x && y && byDD) {
			x = x - canvas.origin.offsetX - 50;
			y = y - canvas.origin.offsetY - 40;
		} else if (x && y) {
			x = x - canvas.origin.offsetX;
			y = y - canvas.origin.offsetY;
		} else {
			x = 100, y = 50;
		}
		var model;
		if (modelConfig.type === 'path') {
			var path = [
				['M', (x - 50), y],
				['L', (x + 50), y]
			], pathConfig = {
				type: 'path',
				data: modelConfig.data,
				attrs: {
					path: path,
					stroke: 'black',
					'stroke-width': 2.5,
					'arrow-end': 'classic-wide-long'
				}
			};
			if (modelConfig.attrs) {
				Ext.apply(pathConfig.attrs, modelConfig.attrs);
			}
			model = canvas.createModel(canvas, pathConfig);
		} else if (modelConfig.type === 'circle') {
			var circleConfig = {
				type: 'circle',
				data: modelConfig.data,
				attrs: {
					cx: x, cy: y, r: modelConfig.r || 20, fill: 'white'
				}
			};
			if (modelConfig.attrs) {
				Ext.apply(circleConfig.attrs, modelConfig.attrs);
			}
			model = canvas.createModel(canvas, circleConfig);
		} else if (modelConfig.type === 'ellipse') {
			var ellipseConfig = {
				type: 'ellipse',
				data: modelConfig.data,
				attrs: {
					cx: x, cy: y,
					rx: modelConfig.rx || 50, ry: modelConfig.ry || 40,
					fill: 'white'
				}
			};
			if (modelConfig.attrs) {
				Ext.apply(ellipseConfig.attrs, modelConfig.attrs);
			}
			model = canvas.createModel(canvas, ellipseConfig);
		} else if (modelConfig.view) {
			var imageConfig = {
				type: 'image',
				data: modelConfig.data,
				attrs: {
					src: modelConfig.view,
					x: x, y: y, fill: 'white',
					width: modelConfig.width || 100, height: modelConfig.height || 80
				}
			};
			if (modelConfig.attrs) {
				Ext.apply(imageConfig.attrs, modelConfig.attrs);
			}
			model = canvas.createModel(canvas, imageConfig);
		} else {
			var rectConfig = {
				type: 'rect',
				data: modelConfig.data,
				attrs: {
					x: x, y: y, fill: 'white',
					width: modelConfig.width || 100, height: modelConfig.height || 80
				}
			};
			if (modelConfig.attrs) {
				Ext.apply(rectConfig.attrs, modelConfig.attrs);
			}
			model = canvas.createModel(canvas, rectConfig);
		}
		if (byDD && canvas.selected.length === 1 && model.type !== 'path') {
			canvas.link(canvas, canvas.selected[0], model);
		}
		canvas.selectModel(canvas, model);
		return model;
	},
	copy: function(canvas) {
		canvas = canvas || this;
		if (canvas.selected.length > 0) {
			canvas.ClipBoard = canvas.selected;
		}
	},
	paste: function(canvas) {
		canvas = canvas || this;
		var newSelected = [], offsetX = 50, offsetY = 50;
		Ext.each(canvas.ClipBoard, function(model) {
			var newModelConfig = {
				type: model.type,
				data: model.data(),
				attrs: Ext.decode(Ext.encode(model.attrs))
			};
			if (model.text) {
				var textConfig = {
					type: 'text',
					attrs: Ext.decode(Ext.encode(model.text.attrs))
				};
				textConfig.attrs.x += offsetX;
				textConfig.attrs.y += offsetY;
				newModelConfig.text = textConfig;
			}
			if (model.type === 'circle' || model.type === 'ellipse') {
				newModelConfig.attrs.cx += offsetX;
				newModelConfig.attrs.cy += offsetY
			} else if (model.type === 'path') {
				var path = newModelConfig.attrs.path;
				Ext.each(path, function(item) {
					item[1] += offsetX;
					item[2] += offsetY;
				});
			} else {
				newModelConfig.attrs.x += offsetX;
				newModelConfig.attrs.y += offsetY;
			}
			var newModel = canvas.createModel(canvas, newModelConfig);
			newSelected.push(newModel);
		});
		canvas.ClipBoard = canvas.selected = newSelected;
		var selectBox = canvas.selectBox, x = selectBox.attrs.x, y = selectBox.attrs.y;
		x += offsetX;
		y += offsetY;
		canvas.selectBox.attr({x: x, y: y});
	},
	removeModel: function(canvas) {
		canvas = canvas || this;
		if (canvas.selected.length > 0) {
			Ext.each(canvas.selected, function(model) {
				if (model.text) {
					model.text.remove();
				}
				if (model.flowPlate) {
					model.flowPlate.remove();
				}

				if (Array.isArray(model.flowFrom)) {
					Ext.each(model.flowFrom, function(ff) {
						var src = ff.flowFrom;
						Ext.Array.remove(src.flowTo, ff);
						if (ff.text) {
							ff.text.remove();
						}
						ff.flowPlate.remove();
						ff.remove();
					});
				} else if (model.flowFrom) {
					Ext.Array.remove(model.flowFrom.flowTo, model);
				}
				if (Array.isArray(model.flowTo)) {
					Ext.each(model.flowTo, function(ft) {
						var target = ft.flowTo;
						Ext.Array.remove(target.flowFrom, ft);
						if (ft.text) {
							ft.text.remove();
						}
						ft.flowPlate.remove();
						ft.remove();
					});
				} else if (model.flowTo) {
					Ext.Array.remove(model.flowTo.flowFrom, model);
				}
				model.remove();
			});
			canvas.selected = [];
			canvas.viewAnchor(canvas, null);
			canvas.selectBox.hide();
			canvas.widget.hide();
		}
	},
	link: function(canvas, src, target) {
		canvas = canvas || this;
		if (src && target) {
			if (src.type === 'path' || target.type === 'path') {
				return;
			} else {
				var path = [
					['M', src.coreX, src.coreY],
					['L', target.coreX, target.coreY]
				], pathConfig = {
					type: 'path',
					attrs: {
						path: path,
						stroke: 'black',
						'stroke-width': 2.5,
						'arrow-end': 'classic-wide-long'
					}
				},
				flow = canvas.createModel(canvas, pathConfig);
				canvas.connect(flow, src, target);
			}
		}
	},
	connect: function(flow, src, target) {
		if (src) {
			if (src.id === 'startP') {
				if (flow.flowFrom) {
					Ext.Array.remove(flow.flowFrom.flowTo, flow);
				}
				flow.flowFrom = null;
			} else {
				flow.flowFrom = src;
				src.flowTo.push(flow);
			}
		} else {
			src = flow.flowFrom;
		}
		if (target) {
			if (target.id === 'endP') {
				if (flow.flowTo) {
					Ext.Array.remove(flow.flowTo.flowFrom, flow);
				}
				flow.flowTo = null;
			} else {
				flow.flowTo = target;
				target.flowFrom.push(flow);
			}
		} else {
			target = flow.flowTo;
		}
		var pi = Math.PI, path = flow.attrs.path, start = flow.start, end = flow.end, angle;

		if (src) {
			var secondStart = [path[1][1], path[1][2]], srcBox = src.getBBox();
			angle = Raphael.angle(src.coreX, src.coreY, secondStart[0], secondStart[1]) - 180;
			if (src.type === 'circle') {
				var r = src.attrs.r + 2, a = r * Math.cos(angle / 180 * pi), b = r * Math.sin(angle / 180 * pi);
				start = [src.coreX + a, src.coreY + b];
			} else {
				if (angle == -135) {
					start[0] = srcBox.x - 2;
					start[1] = srcBox.y - 2;
				} else if (angle == -45) {
					start[0] = srcBox.x + 2;
					start[1] = srcBox.y - 2;
				} else if (angle == 45) {
					start[0] = srcBox.x + 2;
					start[1] = srcBox.y + 2;
				} else if (angle == 135) {
					start[0] = srcBox.x - 2;
					start[1] = srcBox.y + 2;
				} else if (angle > 135 || angle < -135) {
					start[0] = srcBox.x - 2;
					a = src.coreX - start[0];
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					start[1] = src.coreY - b;
				} else if (angle > -135 && angle < -45) {
					angle += 90;
					start[1] = srcBox.y - 2;
					a = src.coreY - start[1];
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					start[0] = src.coreX + b;
				} else if (angle > -45 && angle < 45) {
					start[0] = srcBox.x2 + 2;
					a = start[0] - src.coreX;
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					start[1] = src.coreY + b;
				} else if (angle > 45 && angle < 135) {
					angle -= 90;
					start[1] = srcBox.y2 + 2;
					a = start[1] - src.coreY;
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					start[0] = src.coreX - b;
				}
			}
		}

		if (target) {
			var secondEnd = [path[path.length - 2][1], path[path.length - 2][2]], targetBox = target.getBBox();
			angle = Raphael.angle(target.coreX, target.coreY, secondEnd[0], secondEnd[1]) - 180;
			if (target.type === 'circle') {
				var r = target.attrs.r + 2, a = r * Math.cos(angle / 180 * pi), b = r * Math.sin(angle / 180 * pi);
				end = [target.coreX + a, target.coreY + b];
			} else {
				var a, b;
				if (angle == -135) {
					start[0] = srcBox.x - 2;
					start[1] = srcBox.y - 2;
				} else if (angle == -45) {
					start[0] = srcBox.x + 2;
					start[1] = srcBox.y - 2;
				} else if (angle == 45) {
					start[0] = srcBox.x + 2;
					start[1] = srcBox.y + 2;
				} else if (angle == 135) {
					start[0] = srcBox.x - 2;
					start[1] = srcBox.y + 2;
				} else if (angle > 135 || angle < -135) {
					end[0] = targetBox.x - 2;
					a = target.coreX - end[0];
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					end[1] = target.coreY - b;
				} else if (angle > -135 && angle < -45) {
					angle += 90;
					end[1] = targetBox.y - 2;
					a = target.coreY - end[1];
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					end[0] = target.coreX + b;
				} else if (angle > -45 && angle < 45) {
					end[0] = targetBox.x2 + 2;
					a = end[0] - target.coreX;
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					end[1] = target.coreY + b;
				} else if (angle > 45 && angle < 135) {
					angle -= 90;
					end[1] = targetBox.y2 + 2;
					a = end[1] - target.coreY;
					b = Math.ceil(a * Math.tan(angle / 180 * pi));
					end[0] = target.coreX - b;
				}
			}
		}
		var flowPlate = flow.flowPlate, path = [
			['M', start[0], start[1]],
			['L', end[0], end[1]]
		];
		flow.attr({path: path});
		flowPlate.attr({path: path});
		flowPlate.start = flow.start = start;
		flowPlate.end = flow.end = end;
	},
	setDiagram: function(canvas, diagram) {
		canvas = canvas || this;
		Ext.each(diagram, function(modelConfig) {
			canvas.createModel(canvas, modelConfig);
		});
		Ext.each(diagram, function(modelConfig) {
			var model = canvas.paper.getById(modelConfig.modelId);
			if (Array.isArray(modelConfig.flowFromId)) {
				Ext.each(modelConfig.flowFromId, function(ffi) {
					var flowFrom = canvas.paper.getById(ffi);
					model.flowFrom.push(flowFrom);
				});
			} else {
				model.flowFrom = canvas.paper.getById(modelConfig.flowFromId);
			}

			if (Array.isArray(modelConfig.flowToId)) {
				Ext.each(modelConfig.flowToId, function(fti) {
					var flowTo = canvas.paper.getById(fti);
					model.flowTo.push(flowTo);
				});
			} else {
				model.flowTo = canvas.paper.getById(modelConfig.flowToId);
			}
		});
	},
	getDiagram: function(canvas) {
		canvas = canvas || this;
		var ms = canvas.modelSet;
		if (!ms) {
			ms = canvas.modelSet = canvas.paper.setFinish();
		}
		var diagram = [];
		Ext.each(ms.items, function(model) {
			if (model.type !== 'text' && !model.flow) {
				var modelData = model.data();
				var modelConfig = {
					modelId: model.id, type: model.type,
					attrs: model.attrs,
					data: modelData
				};
				if (modelData.text) {
					modelConfig.text = {
						type: 'text',
						attrs: model.text.attrs
					};
				}
				if (Array.isArray(model.flowFrom)) {
					modelConfig.flowFromId = [];
					Ext.each(model.flowFrom, function(ff) {
						modelConfig.flowFromId.push(ff.id);
					});
				} else if (model.flowFrom) {
					modelConfig.flowFromId = model.flowFrom.id;
				}
				if (Array.isArray(model.flowTo)) {
					modelConfig.flowToId = [];
					Ext.each(model.flowTo, function(ft) {
						modelConfig.flowToId.push(ft.id);
					});
				} else if (model.flowTo) {
					modelConfig.flowToId = model.flowTo.id;
				}
				diagram.push(modelConfig);
			}
		});
		canvas.paper.setStart(ms);
		return diagram;
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.canvas.Widget', {
	extend: 'Ext.container.Container',
	canvas: null,
	width: 46,
	defaults: {
		columnWidth: .5
	},
	initComponent: function() {
		var me = this;
		me.initQuickSvg(me);
		me.items = me.quickSvg;
		me.callParent();
	},
	initQuickSvg: function(me) {
		me.quickSvg = [
			Ext.create('Ext.button.Button', {
				name: 'image',
				iconCls: 'User',
//				text: '圆形',
				handler: me.newModel,
				canvas: me.canvas,
				attrs: {width: 100, height: 80}
			}),
			Ext.create('Ext.button.Button', {
				name: 'circle',
				iconCls: 'Circle',
//				text: '圆形',
				handler: me.newModel,
				canvas: me.canvas
			}),
			Ext.create('Ext.button.Button', {
				name: 'rect',
				iconCls: 'Rect',
//				text: '矩形',
				handler: me.newModel,
				canvas: me.canvas
			}),
			Ext.create('Ext.button.Button', {
				name: 'ellipse',
				iconCls: 'Ellipse',
//				text: '椭圆',
				handler: me.newModel,
				canvas: me.canvas
			}),
			Ext.create('Ext.button.Button', {
				name: 'path',
				iconCls: 'Path',
//				text: '箭头',
				handler: me.newModel,
				canvas: me.canvas
			})
		];
	},
	newModel: function() {
		var type = this.name, canvas = this.canvas, origin = canvas.origin, modelConfig = {
			type: type
		};
		if (type === 'image') {
			modelConfig.view = this.view;
		}
		if (this.attrs) {
			modelConfig.attrs = this.attrs;
		}
		if (canvas.selected.length === 1 && type !== 'path') {
			var selectedModel = canvas.selected[0], x, y;
			if (type === 'circle' || type === 'ellipse') {
				x = selectedModel.coreX + 150;
				y = selectedModel.coreY + origin.offsetY;
			} else {
				x = selectedModel.coreX + 150;
				y = selectedModel.coreY + origin.offsetY - 40;
			}
			x += origin.offsetX;
			var newModel = canvas.addModel(canvas, modelConfig, x, y);
			canvas.link(canvas, selectedModel, newModel);
		} else if (type !== 'path') {
			canvas.addModel(canvas, modelConfig);
		}
	},
	afterFirstLayout: function() {
		var me = this, canvas = me.canvas;
		me.callParent();
		new Ext.dd.DragSource(me.items.items[4].getId(), {
			group: 'pathDD',
			afterDragDrop: function(target, e, id) {
				var canvas = Ext.getCmp(id);
				canvas.link(canvas, canvas.selected[0], canvas.target);
			}
		});
		var target = new Ext.dd.DDTarget(canvas.getId(), 'pathDD');
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.canvas.Quickbar', {
	extend: 'Ext.toolbar.Toolbar',
	canvas: null,
	initComponent: function() {
		var me = this;
		me.initQuickBtn(me);
		me.items = me.quickBtn;
		me.callParent();
	},
	initQuickBtn: function(me) {
		me.quickBtn = [
			{
				name: 'copy',
				text: '复制',
				canvas: me.canvas,
				handler: me.doOperation
			},
			{
				name: 'paste',
				text: '粘贴',
				canvas: me.canvas,
				handler: me.doOperation
			},
			{
				name: 'removeModel',
				text: '删除',
				canvas: me.canvas,
				handler: me.doOperation
			}
		];
	},
	doOperation: function() {
		var operation = this.name, canvas = this.canvas;
		canvas[operation](canvas);
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.canvas.SelectBox', {
	selecteBox: null,
	lineX: null,
	lineY: null,
	initLineXY: function(canvas) {
		var canvas = canvas || this, lineXConfig = {
			modelId: 'lineX',
			type: 'path',
			attrs: {
				path: [['M', 0, 0], ['L', 0, canvas.getHeight()]],
				fill: 'none', stroke: 'green', 'stroke-width': 1,
				'stroke-linecap': 'round',
				'stroke-linejoin': 'round',
				'stroke-dasharray': "-"
			}
		}, lineYConfig = {
			modelId: 'lineX',
			type: 'path',
			attrs: {
				path: [['M', 0, 0], ['L', canvas.getWidth(), 0]],
				fill: 'none', stroke: 'green', 'stroke-width': 1,
				'stroke-linecap': 'round',
				'stroke-linejoin': 'round',
				'stroke-dasharray': "-"
			}
		};
		canvas.lineX = canvas.mixins[lineXConfig.type].init(canvas, lineXConfig, true).hide();
		canvas.lineY = canvas.mixins[lineXConfig.type].init(canvas, lineYConfig, true).hide();
	},
	initSelectBox: function(canvas) {
		var selectBoxConfig = {
			modelId: 'selectBox',
			type: 'rect',
			attrs: {
				fill: 'none', stroke: 'blue', 'stroke-width': 1,
				'stroke-linecap': 'round',
				'stroke-linejoin': 'round',
				'stroke-dasharray': "-"
			}
		};
		canvas.selectBox = canvas.createModel(canvas, selectBoxConfig).hide();
	},
	setAnchor: function(canvas, selectBox, xy) {
		selectBox.anchorX = xy[0], selectBox.anchorY = xy[1];
		selectBox.attr({x: xy[0], y: xy[1], width: 0, height: 0}).show().toFront();
		selectBox.view = true;
	},
	changeSelectBox: function(canvas, selectBox, xy) {
		var x, y, width, height;
		if (selectBox.anchorX < xy[0]) {
			x = selectBox.anchorX;
			width = xy[0] - x;
		} else {
			x = xy[0];
			width = selectBox.anchorX - x;
		}
		if (selectBox.anchorY < xy[1]) {
			y = selectBox.anchorY;
			height = xy[1] - y;
		} else {
			y = xy[1];
			height = selectBox.anchorY - y;
		}
		selectBox.attr({
			x: x - canvas.origin.offsetX, y: y - canvas.origin.offsetY,
			width: width, height: height
		});
	},
	selectModel: function(canvas, model) {
		var selectBox = canvas.selectBox, bbox,
				minX = canvas.getWidth(), minY = canvas.getHeight(), maxX = 0, maxY = 0;
		canvas.focus();
		canvas.selected = [];
		canvas.viewAnchor(canvas, null);
		canvas.widget.hide();
		if (model) {
			canvas.selected = [model];
			if (model.type === 'path') {
				canvas.viewAnchor(canvas, model);
			} else {
				bbox = model.getBBox(), minX = bbox.x, minY = bbox.y, maxX = bbox.x2, maxY = bbox.y2;
				selectBox.attr({x: minX, y: minY, width: maxX - minX, height: maxY - minY}).show();
				selectBox.view = true;
				canvas.widget.show();
				canvas.widget.setXY([bbox.x2 + canvas.origin.offsetX + 2, bbox.y + canvas.origin.offsetY]);
			}
		} else if (canvas.selected.length == 0) {
			var ms = canvas.modelSet = canvas.paper.setFinish();
			Ext.each(ms, function(model) {
				if (model.type !== 'path' && model.type !== 'text'
						&& canvas.selectBox.isPointInside(model.coreX, model.coreY)) {
					canvas.selected.push(model);
					bbox = model.getBBox();
					minX = minX < bbox.x ? minX : bbox.x;
					minY = minY < bbox.y ? minY : bbox.y;
					maxX = maxX > bbox.x2 ? maxX : bbox.x2;
					maxY = maxY > bbox.y2 ? maxY : bbox.y2;
				}
			});
			if (canvas.selected.length > 0) {
				canvas.selectBox.attr({x: minX, y: minY, width: maxX - minX, height: maxY - minY});
			} else {
				canvas.selectBox.hide();
				canvas.selectBox.view = false;
			}
			canvas.paper.setStart(ms);
		}
		selectBox.oldX = selectBox.attrs.x;
		selectBox.oldY = selectBox.attrs.y;
	},
	viewAnchor: function(me, model) {
		var anchor = me.anchor;
		for (var i in anchor) {
			anchor[i].hide();
			anchor[i].toFront();
		}
		if (!model) {
			return;
		} else if (model.type === 'path') {
			var flow = model;
			me.selectBox.hide();
			me.selectBox.view = false;
			var ff = flow.flowFrom, ft = flow.flowTo,
					path = flow.attrs.path, len = path.length,
					start = flow.start, secondStart = [path[1][1], path[1][2]],
					end = flow.end, secondEnd = [path[len - 2][1], path[len - 2][2]];
			var pi = Math.PI, angle;
			if (ff) {
				anchor.startP.attr({
					cx: ff.coreX, cy: ff.coreY, fill: 'red', 'fill-opacity': 1
				}).show();
			} else {
				anchor.startP.attr({cx: start[0], cy: start[1], fill: 'white'}).show();
			}
			if (ft) {
				anchor.endP.attr({
					cx: ft.coreX, cy: ft.coreY, fill: 'red', 'fill-opacity': 1
				}).show();
			} else {
				anchor.endP.attr({cx: end[0], cy: end[1], fill: 'white'}).show();
			}
		}
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.canvas.KeyMap', {
	//ctrl+c
	'ctrl+c': function(canvas) {
		canvas.copy(canvas);
	},
	//ctrl+v
	'ctrl+v': function(canvas) {
		canvas.paste(canvas);
	},
	//Delete
	'del': function(canvas) {
		canvas.removeModel(canvas);
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.TopToolbar', {
	extend: 'Ext.toolbar.Toolbar',
	canvas: null,
	initUtil: null,
	initComponent: function() {
		var me = this;
		me.items = [
			{
				iconCls: 'SaveButton',
				handler: function() {
					var canvas = me.canvas, diagram = canvas.getDiagram(),
							saveDialog = Ext.create('SvgEditor.module.SaveDialog');
					diagram = {diagram: diagram};
					var diagramJSON = Ext.encode(diagram);
					saveDialog.modelDescribe.setValue(diagramJSON);
					saveDialog.show();
				}
			},
			{
				text: '打开',
				iconCls: '',
				handler: function() {
					var canvas = me.canvas;
					canvas.initCanvas(canvas);
					var diagramJSON =
							'{"diagram":[{"modelId":"start","type":"circle","attrs":{"cx":100,"cy":200,"r":20,"fill":"#00ff33","stroke":"#000","fill-opacity":1},"data":{"text":"start"},"text":{"type":"text","attrs":{"x":100,"y":230,"text-anchor":"middle","text":"start","font":"14px \u5b8b\u4f53","stroke":"none","fill":"#000"}},"flowFromId":[],"flowToId":["path-3","path-8","path-9"]},{"modelId":"end","type":"circle","attrs":{"cx":915,"cy":200,"r":20,"fill":"red","stroke":"#000","fill-opacity":1},"data":{"text":"end"},"text":{"type":"text","attrs":{"x":914.9999999999999,"y":230,"text-anchor":"middle","text":"end","font":"14px \u5b8b\u4f53","stroke":"none","fill":"#000"}},"flowFromId":["path-10","path-11","path-12"],"flowToId":[]},{"modelId":"image-2","type":"image","attrs":{"x":423,"y":67,"width":102,"height":82,"src":"model/view/activity/usertask.svg","fill":"white"},"data":{"a":"a1","b":"b2","c":"c3","text":"\u4efb\u52a11"},"text":{"type":"text","attrs":{"x":474,"y":159,"text-anchor":"middle","text":"\u4efb\u52a11","font":"14px \u5b8b\u4f53","stroke":"none","fill":"#000"}},"flowFromId":["path-3"],"flowToId":["path-5","path-12"]},{"modelId":"path-3","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",121.36314290740077,194.74489532759125],["L",421,121]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"start","flowToId":"image-2"},{"modelId":"image-4","type":"image","attrs":{"x":421,"y":244,"width":102,"height":82,"src":"model/view/activity/usertask.svg","fill":"white"},"data":{"a":"a1","b":"b2","c":"c3","text":"\u4efb\u52a12"},"text":{"type":"text","attrs":{"x":472,"y":336,"text-anchor":"middle","text":"\u4efb\u52a12","font":"14px \u5b8b\u4f53","stroke":"none","fill":"#000"}},"flowFromId":["path-5","path-8"],"flowToId":["path-7","path-11"]},{"modelId":"path-5","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",473,151],["L",473,242]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"image-2","flowToId":"image-4"},{"modelId":"image-6","type":"image","attrs":{"x":421,"y":436,"width":102,"height":82,"src":"model/view/activity/usertask.svg","fill":"white"},"data":{"a":"a1","b":"b2","c":"c3","text":"\u4efb\u52a13"},"text":{"type":"text","attrs":{"x":472,"y":528,"text-anchor":"middle","text":"\u4efb\u52a13","font":"14px \u5b8b\u4f53","stroke":"none","fill":"#000"}},"flowFromId":["path-7","path-9"],"flowToId":["path-10"]},{"modelId":"path-7","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",472,328],["L",472,434]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"image-4","flowToId":"image-6"},{"modelId":"path-8","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",121.44724490829546,204.90058015377718],["L",419,272]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"start","flowToId":"image-4"},{"modelId":"path-9","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",117.64543187171391,213.13920599049666],["L",419,437]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"start","flowToId":"image-6"},{"modelId":"path-10","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",525,444],["L",896.3464032824519,211.66376137869258]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"image-6","flowToId":"end"},{"modelId":"path-11","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",525,275],["L",893.3941206967979,204.1455976089665]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"image-4","flowToId":"end"},{"modelId":"path-12","type":"path","attrs":{"fill":"none","stroke":"black","path":[["M",527,120],["L",893.4636504104661,195.50715609470043]],"stroke-width":2.5,"arrow-end":"classic-wide-long"},"data":{},"flowFromId":"image-2","flowToId":"end"}]}';
					if (diagramJSON) {
						var diagram = Ext.decode(diagramJSON).diagram;
						canvas.setDiagram(canvas, diagram);
					}
				}
			},
			{
				text: '重置',
				iconCls: '',
				handler: function() {
					var canvas = me.canvas;
					canvas.initCanvas(canvas);
					if (me.initUtil) {
						me.initUtil.init(canvas);
					}
				}
			},
			{
				text: '清空',
				iconCls: '',
				handler: function() {
					var canvas = me.canvas;
					canvas.initCanvas(canvas);
				}
			}
		];
		me.callParent();
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.CanvasPanel', {
	extend: 'Ext.panel.Panel',
	mixins: {
		image: 'SvgEditor.graph.Image',
		circle: 'SvgEditor.graph.Circle',
		ellipse: 'SvgEditor.graph.Ellipse',
		path: 'SvgEditor.graph.Path',
		rect: 'SvgEditor.graph.Rect',
		anchor: 'SvgEditor.graph.Anchor',
		text: 'SvgEditor.graph.Text',
		selectBox: 'SvgEditor.canvas.SelectBox',
		keyMap: 'SvgEditor.canvas.KeyMap',
		operation: 'SvgEditor.canvas.Operation'
	},
	layout: 'absolute',
	paper: null,
	quickbar: null,
	readOnly: false,
	nowId: 0,
	modelIds: [],
//	img: null,
	enableDragDrop: true,
	origin: {offsetX: 0, offsetY: 0},
	anchor: {startP: null, endP: null},
	selected: [],
	takeUp: null,
	target: null,
	ClipBoard: null,
	modelSet: null,
	initComponent: function() {
		var me = this;
		if (!me.readOnly) {
			me.initTextView(me);
//		me.img = Ext.create('Ext.Img');
			me.quickbar = me.tbar = Ext.create('SvgEditor.canvas.Quickbar', {canvas: me});
			me.widget = Ext.create('SvgEditor.canvas.Widget', {hidden: true, canvas: me});
			me.items = [me.textView, me.widget];//, me.img];
		}
		me.callParent();
	},
	initTextView: function(me) {
		me.textView = Ext.create('Ext.form.field.TextArea', {
			hidden: true,
			thisModel: null,
			width: 100,
			rows: 3,
			focused: false,
			setText: function(model) {
				var text = this.getValue();
				if (model.text && this.isDirty()) {
					model.text.attr({text: text});
				} else {
					var bbox = model.getBBox(), textConfig = {
						type: 'text',
						attrs: {
							x: model.coreX, y: bbox.y2 + 10,
							text: text, font: "14px 宋体"
						}
					};
					model.text = me.createModel(me, textConfig);
					model.text.model = model;
				}
				model.data('text', text);
			},
			getText: function(model) {
				var text = model.data('text');
				this.setValue(text);
			},
			listeners: {
				blur: {
					fn: function() {
						this.setText(this.thisModel);
						this.thisModel = null;
						this.reset();
						this.hide();
						this.focused = false;
					}
				},
				focus: {
					fn: function() {
						this.focused = true;
						this.thisModel = me.selected[0];
						this.getText(this.thisModel);
						me.widget.setX(me.selectBox.attrs.x + me.origin.offsetX - me.widget.getWidth());
					}
				}
			}
		});
	},
	afterFirstLayout: function() {
		var me = this;
		me.initCanvas(me);
	},
	initCanvas: function(me) {
		if (me.paper) {
			me.modelSet = me.paper.setFinish();
			Ext.each(me.modelSet, function(model) {
				model.removeData();
				if (model.text) {
					model.text.remove();
				}
				if (model.flowPlate) {
					model.flowPlate.remove();
				}
				model.remove();
			});
			for (var i in me.anchor) {
				me.anchor[i].remove();
			}
			if (me.selectBox) {
				me.selectBox.remove();
			}
			if (me.lineX && me.lineY) {
				me.lineX.remove();
				me.lineY.remove();
			}
			me.paper.remove();
		}
		me.nowId = 0;
		me.modelIds = [];
		me.paper = Raphael(me.body.id, me.getWidth(), me.getHeight());
		me.paper.renderfix();
		me.origin.offsetX = me.getX();
		me.origin.offsetY = me.getY();
		if (me.quickbar) {
			me.origin.offsetY += me.quickbar.getHeight();
		}
		for (var i in me.anchor) {
			var anchorConfig = {
				modelId: i,
				type: 'circle',
				attrs: {
					r: 3, fill: 'white', 'fill-opacity': 0
				}
			};
			me.anchor[i] = me.mixins.anchor.init(me, anchorConfig).hide();
		}
		me.initSelectBox(me);
		me.initLineXY(me);
		me.widget.hide();
		me.selected = [];
		me.target = null;
		me.modelSet = null;
		me.start = null;
		me.end = null;
		me.paper.setStart();
	},
	createId: function(canvas, type, id) {
		var me = canvas || this;
		if (!id) {
			id = type + '-' + (++me.nowId);
		}
		while (Ext.Array.contains(me.modelIds, id)) {
			id = type + '-' + (++me.nowId);
		}
		me.modelIds.push(id);
		return id;
	},
	getModel: function(canvas, e, t, xy) {
		var model, canvas = canvas || this;
		if (t.raphael) {
			model = canvas.paper.getById(t.raphaelid);
		} else {
			xy = xy ? xy : e.getXY();
			model = canvas.paper.getElementByPoint(xy[0], xy[1])
		}
		if (model && model.type === 'text' && model.model) {
			model = model.model;
		} else if (model && model.type === 'path' && model.flow) {
			model = model.flow;
		}
		return model;
	},
	setData: function(model, key, value) {
		if (model && key && value) {
			model.data(key, value);
			return true;
		} else if (model && key && (typeof key === 'object')) {
			model.data(key);
			return true;
		} else {
			return false;
		}
	},
	getData: function(model, key) {
		if (model && key) {
			return model.data(key);
		} else if (model) {
			return model.data();
		} else {
			return null;
		}
	},
	removeData: function(model, key) {
		if (model && key) {
			model.removeData(key);
			return true;
		} else if (model) {
			model.removeData();
			return true;
		} else {
			return false;
		}
	},
	afterRender: function() {
		var me = this;
		me.callParent();
		if (!me.readOnly) {
			me.el.on('dblclick', me.onDblClick, me);
			me.el.on('mousedown', me.onMousedown, me);
			me.el.on('mousemove', me.onMousemove, me);
			me.el.on('mouseup', me.onMouseup, me);
			me.initKeyMap(me);
		}
	},
	onDblClick: function(e, t) {
		var me = this, textView = me.textView, xy = e.getXY(), model;
		if (model = me.getModel(me, e, t)) {
			me.selectModel(me, model);
			textView.show();
			textView.setXY(xy);
			textView.focus();
		}
	},
	onMousedown: function(e, t) {
		var me = this, xy = e.getXY(), model = me.getModel(me, e, t), cmp = me.getChildByElement(t);
		if (!(cmp === me.textView || cmp === me.quickbar || cmp === me.widget)) {
			if (model && me.anchor.hasOwnProperty(model.id)) {
				return;
			} else {
				if (!Ext.Array.contains(me.selected, model)) {
					me.selectModel(me, model);
				}
				if (!model) {
					me.setAnchor(me, me.selectBox, xy);
				} else {
					var selectBox = me.selectBox;
					me.takeUp = model;
					if (!selectBox.view) {
						me.selectModel(me, model);
					}
				}
				me.mousedown = true;
			}
		}
	},
	onMousemove: function(e, t) {
		var me = this;
		if (me.mousedown && me.selectBox.view && !me.takeUp) {
			var xy = e.getXY();
			me.changeSelectBox(me, me.selectBox, xy);
			me.mousemove = true;
		}
	},
	onMouseup: function(e, t) {
		var me = this, cmp = me.getChildByElement(t);
		me.target = null;
		if (!(me.textView.focused || cmp === me.textView || cmp === me.quickbar || cmp === me.widget)) {
			if (me.selectBox.view && !me.takeUp) {
				me.selectModel(me);
			}
			if (me.selected.length == 1 && me.selected[0].type !== 'path') {
				var bbox = me.selectBox.getBBox();
				me.widget.show();
				me.widget.setXY([bbox.x2 + me.origin.offsetX + 2, bbox.y + me.origin.offsetY]);
			}
			if (me.selected.length == 1 && t.raphael && me.selected[0].id !== t.raphaelid) {
				me.target = me.getModel(me, e, t);
			}
			if (me.selected.length == 1 && me.selected[0].type !== 'path') {
				var bbox = me.selectBox.getBBox();
				me.widget.show();
				me.widget.setXY([bbox.x2 + me.origin.offsetX + 2, bbox.y + me.origin.offsetY]);
			}
		}
		me.takeUp = null;
		me.mousemove = false;
		me.mousedown = false;
	},
	initKeyMap: function(me) {
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			ctrl: true,
			key: Ext.EventObject.C,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['ctrl+c'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			ctrl: true,
			key: Ext.EventObject.V,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['ctrl+v'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
		Ext.create('Ext.util.KeyMap', {
			target: me.getId(),
			key: Ext.EventObject.DELETE,
			canvas: me,
			fn: function(key, ev) {
				this.canvas['del'](this.canvas);
				ev.stopEvent();
				return false;
			}
		});
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.ModelTree', {
	extend: 'Ext.tree.Panel',
	title: 'BPMN 2.0 Model',
	rootVisible: false,
	enableDragDrop: true,
	viewConfig: {
		plugins: {
			ptype: 'treeviewdragdrop',
			ddGroup: 'model-to-canvas',
			enableDrop: false
		}
	},
	initComponent: function() {
		var me = this;
		me.initModel(me);
		me.initTbar(me);
		me.callParent();
	},
	initModel: function(me) {
		me.store = Ext.create('Ext.data.TreeStore', {
			fields: [
				{name: 'id', type: 'string'},
				{name: 'text', type: 'string'},
				{name: 'icon', type: 'string'},
				{name: 'leaf', type: 'bool'},
				{name: 'type', type: 'string'},
				{name: 'view', type: 'string'},
				{name: 'data', type: 'object'},
				{name: 'propertyPackages', type: 'string'},
				{name: 'roles', type: 'string'}
			],
			proxy: {
				type: 'ajax',
				url: 'model/Model_' + system.locale + '.json',
				reader: {
					type: 'json'
//					root: 'model'
				}
			}
		});
	},
	initTbar: function(me) {
		me.filterField = Ext.create('Ext.form.field.Text', {
			xtype: 'textfield',
			fieldLabel: '筛选',
			labelWidth: 40
		});
		me.filterField.on('change', function() {
			me.filterBy(this.getValue(), 'text');
		});
		me.tbar = Ext.create('Ext.form.Panel', {
			layout: 'fit',
			frame: true,
			items: [me.filterField]
		});
	},
	filterBy: function(text, by) {
		this.clearFilter();
		var view = this.getView(),
				me = this,
				nodesAndParents = [];
		// Find the nodes which match the search term, expand them.
		// Then add them and their parents to nodesAndParents.
		this.getRootNode().cascadeBy(function(tree, view) {
			var currNode = this;

			if (currNode && currNode.data[by] && currNode.data[by].toString().toLowerCase().indexOf(text.toLowerCase()) > -1) {
				me.expandPath(currNode.getPath());
				while (currNode.parentNode) {
					nodesAndParents.push(currNode.id);
					currNode = currNode.parentNode;
				}
			}
		}, null, [me, view]);
		// Hide all of the nodes which aren't in nodesAndParents
		this.getRootNode().cascadeBy(function(tree, view) {
			var uiNode = view.getNodeByRecord(this);
			if (uiNode && !Ext.Array.contains(nodesAndParents, this.id)) {
				Ext.get(uiNode).setDisplayed('none');
			}
		}, null, [me, view]);
	},
	clearFilter: function() {
		var view = this.getView();
		this.getRootNode().cascadeBy(function(tree, view) {
			var uiNode = view.getNodeByRecord(this);
			if (uiNode) {
				Ext.get(uiNode).setDisplayed('table-row');
			}
		}, null, [this, view]);
	},
	afterFirstLayout: function() {
		var me = this;
		me.callParent(arguments);
		var canvas = me.up().canvas, body = canvas.body;
		me.cavnasDropTarget = new Ext.dd.DropTarget(body, {
			ddGroup: 'model-to-canvas',
			notifyEnter: function(ddSource, e, data) {
				//Add some flare to invite drop.
				body.stopAnimation();
				body.highlight();
			},
			notifyDrop: function(ddSource, e, data) {
				var nodeConfig = data.records[0].data;
				var xy = e.getXY();
				canvas.addModel(canvas, nodeConfig, xy[0], xy[1], true);
				return true;
			}
		});
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.SaveDialog', {
	extend: 'Ext.window.Window',
	layout: 'fit',
	width: 400,
	height: 300,
	buttonAlign: 'center',
	closable: false,
	initComponent: function() {
		var me = this;
		me.initForm(me);
		me.initBtns(me);
		me.items = [me.form];
		me.callParent();
	},
	initForm: function(me) {
		me.modelName = Ext.create('Ext.form.field.Text',
				{
					xtype: 'textfield',
					name: 'modelName',
					fieldLabel: '模型名称',
					anchor: '100%'
				});
		me.modelDescribe = Ext.create('Ext.form.field.TextArea', {
			name: 'modelDescribe',
			labelAlign: 'top',
			fieldLabel: '模型描述',
			anchor: '100% -50'
		});
		me.form = Ext.create('Ext.form.Panel', {
			fieldDefaults: {
				labelWidth: 60,
				margin: '10 10 0 10'
			},
			items: [me.modelName, me.modelDescribe]
		});
	},
	initBtns: function(me) {
		me.buttons = [
			{
				text: '确认'
			},
			{
				text: '取消',
				handler: function() {
					me.close();
				}
			}
		];
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.module.EditorPanel', {
	extend: 'Ext.panel.Panel',
	layout: 'border',
	readOnly: false,
	initComponent: function() {
		var me = this;
		me.initCanvas(me);
		me.initModelTree(me);
		me.initTbar(me);
		me.items = [me.modelTree, me.canvas];
		me.callParent();
	},
	initCanvas: function(me) {
		me.canvas = Ext.create('SvgEditor.module.CanvasPanel', {
			region: 'center',
			readOnly: me.readOnly
		});
	},
	initModelTree: function(me) {
		me.modelTree = Ext.create('SvgEditor.module.ModelTree', {
			region: 'west',
			width: 200
		});
	},
	initTbar: function(me) {
		me.tbar = me.topBar = Ext.create('SvgEditor.module.TopToolbar', {canvas: me.canvas});
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.init.InitWork', {
	init: function(canvas) {
		var startConfig = {
			modelId: 'start',
			type: 'circle',
			attrs: {
				cx: 100, cy: 200, r: 20,
				fill: '#00ff33', 'fill-opacity': 1
			}
		}, endConfig = {
			modelId: 'end',
			type: 'circle',
			attrs: {
				cx: canvas.getWidth() - 100, cy: 200, r: 20,
				fill: 'red', 'fill-opacity': 1
			}
		};
		;
		canvas.start = canvas.createModel(canvas, startConfig);
		canvas.end = canvas.createModel(canvas, endConfig);
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.init.Init', {
	mixins: {
		initWork: 'SvgEditor.init.InitWork'
	},
	init: function(canvas) {
		var me = this;
		me.mixins.initWork.init(canvas);
		canvas.widget.quickSvg[0].view = 'model/view/activity/usertask.svg';
	}
});/**
 *
 * @author 朱雀
 */
Ext.define('SvgEditor.init.Editor', {
	readOnly: false,
	constructor: function(config) {
		var me = this;
		if (config) {
			Ext.apply(me, config);
		}
		me.init(me);
	},
	init: function(me) {
		Ext.QuickTips.init();
		me.ep = Ext.create('SvgEditor.module.EditorPanel', {readOnly: me.readOnly});
		var viewport = new Ext.container.Viewport({
			layout: 'fit',
			items: [me.ep]
		});
	},
	AJAX: function(method, url, config) {
		var returnText = null;
		Ext.Ajax.request({
			url: url,
			async: false,
			method: method,
			params: config == null ? null : config.params,
			jsonData: config == null ? null : config.jsonData,
			form: config == null ? null : config.form,
			success: function(request) {
				returnText = request.responseText;
				if (returnText == null || returnText == "") {
					returnText = true;
				}
			},
			failure: function() {
				returnText = null;
			}
		});
		return returnText;
	}
});
